package com.luhui.codereview.swing

import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.ui.components.JBScrollPane
import com.intellij.ui.components.JBTabbedPane
import com.intellij.ui.table.JBTable
import com.luhui.codereview.api.ApiManager
import com.luhui.codereview.dto.ReviewResultDto
import com.luhui.codereview.enums.CodeReviewLevelEnum
import com.luhui.codereview.getMessage
import com.luhui.codereview.service.ProjectService
import com.luhui.codereview.token.LocalUserInfoHodler
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.awt.EventQueue
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.JComboBox
import javax.swing.JTable
import javax.swing.JTextArea
import javax.swing.table.DefaultTableModel

/**
 * 代码review列表tab
 * @author  luhui
 * @date  2019/11/18 19:49
 * @version 1.0
 */
class ViewTabTable (
        val viewTabTableApplication: ViewTabTableApplication

) : JBTable() {

    private var currentTaleData:List<ReviewResultDto>? = null



    init {
        this.autoResizeMode = JTable.AUTO_RESIZE_OFF
        this.addMouseListener(object : MouseAdapter() {
            override fun mouseClicked(e: MouseEvent?) {
                if (e?.clickCount == 2) {
                    //双击
                    val rowIndex = (e.source as JTable).rowAtPoint(e.point) //获得行位置
                    if (currentTaleData != null) {
                        onDoubleClick(currentTaleData!![rowIndex])
                    }
                }
            }
        })
    }

    data class ViewTabTableApplication(
            val project:Project,
            /**
             * 最外层的容器
             */
            var jBTabbedPane: JBTabbedPane? = null,

            /**
             * 有问题代码的多行文本哉
             */
            var origCodeTextArea: JTextArea?= null,

            /**
             * 指派人描述信息的多行文本域
             */
            var contextTestArea : JTextArea?= null,

            /**
             * 严重级别下拉框
             */
            var levelComboBox: JComboBox<String>?= null
    )

    abstract class BaseViewTabTable(viewTable:ViewTabTable) : JBScrollPane(viewTable){

        /**
         * 刷新列表
         */
        abstract fun refresh()

        abstract fun getApplicationContext() : ViewTabTableApplication
    }

    /**
     * 对table包装的pane
     */
    private inner class ViewTab : BaseViewTabTable(this@ViewTabTable) {
        override fun getApplicationContext(): ViewTabTableApplication {
            return viewTabTableApplication
        }

        init {
            loadTableData(false)
        }

        override fun refresh(){
            loadTableData(true)
        }
    }

    companion object {

        /**
         * 创建这个Tab
         */
         fun buildViewTab(project: Project) : BaseViewTabTable {
            val table = ViewTabTable(ViewTabTableApplication(project))
            return table.ViewTab()
        }

    }

    override fun isCellEditable(row: Int, column: Int): Boolean {
        return false
    }



    /**
     * 跳转到指定文件
     */
    private fun onDoubleClick(reviewResultDto: ReviewResultDto){
        val project = viewTabTableApplication.project
        val virtualFile = project.baseDir.findFileByRelativePath(reviewResultDto.fileName)
        val fileEditorManager = FileEditorManager.getInstance(project) ?: return
        fileEditorManager.openFile(virtualFile!!,true)
        val editor = fileEditorManager.selectedTextEditor?:return
        val caretModel = editor.caretModel
        //在Editor中位置分为两种，一种是逻辑位置，对应LogicalPosition类；另一种是视觉位置，对应VisualPosition类。具体介绍见：https://www.jianshu.com/p/59a0826841fe
        //跳转到指定行(逻辑位置)
        caretModel.moveToLogicalPosition(LogicalPosition(reviewResultDto.codeLineStart,reviewResultDto.codeColumnStart))

        viewTabTableApplication.jBTabbedPane?.selectedIndex = 1
        viewTabTableApplication.origCodeTextArea?.text = reviewResultDto.code
        viewTabTableApplication.contextTestArea?.text = reviewResultDto.content
        viewTabTableApplication.levelComboBox?.selectedItem = reviewResultDto.levelDesc
//        val selectModel = editor.selectionModel
//        selectModel.selectLineAtCaret()
    }


    /**
     * 加载表格数据
     */
    private fun loadTableData(showError:Boolean) {
        val userId = LocalUserInfoHodler.localUserInfo?.id
        if(userId==null){
            if(showError) {
                Messages.showErrorDialog(getMessage("scanQrCode.userNotAuth.msg"), getMessage("notFoundProjectId.title"))
            }
            return
        }
        val projectId = ProjectService.getInstance(viewTabTableApplication.project).getCurrentProjectInfo()?.id
        if(projectId==null){
            EventQueue.invokeLater{
                if(showError) {
                    Messages.showErrorDialog(getMessage("notFoundProjectId.msg"), getMessage("notFoundProjectId.title"))
                }
            }
            return
        }
        GlobalScope.launch {
            val codeList = ApiManager.getApiInstance().codeList(userId,projectId)
            val model = initModel()
            for (reviewResultDto in codeList) {
                reviewResultDto.levelDesc = reviewResultDto.level?.let { CodeReviewLevelEnum.getDescByCode(it) }
            }
            currentTaleData = codeList
            for (data in codeList) {
                model.addRow(arrayOf(data.initiatorName, data.receiverName, data.createTime, data.fileName, "${data.codeLineStart}:${data.codeColumnStart}",
                        "${data.codeLineEnd}:${data.codeColumnEnd}", data.levelDesc, data.code, data.content))
            }
        }
    }

    private fun initModel(): DefaultTableModel {
        val model = DefaultTableModel()
        model.setColumnIdentifiers(arrayOf(getMessage("tab.table.column.initiatorName.text"), getMessage("tab.table.column.receiverName.text"),
                getMessage("tab.table.column.createTime.text"), getMessage("tab.table.column.fileName.text"),
                getMessage("tab.table.column.startPosition.text"), getMessage("tab.table.column.endPosition.text"),
                getMessage("tab.table.column.level.text"), getMessage("tab.table.column.code.text"), getMessage("tab.table.column.content.text")))
        this.model = model
        this.columnModel.getColumn(0).preferredWidth = 50
        this.columnModel.getColumn(1).preferredWidth = 50
        this.columnModel.getColumn(2).preferredWidth = 100
        this.columnModel.getColumn(3).preferredWidth = 300
        this.columnModel.getColumn(4).preferredWidth = 100
        this.columnModel.getColumn(5).preferredWidth = 100
        this.columnModel.getColumn(6).preferredWidth = 80
        this.columnModel.getColumn(8).preferredWidth = 400
        this.columnModel.getColumn(7).preferredWidth = 400
        return model
    }



}